#include "music_system.h"

music::music_system::music_system()
{
	_model.reset(new model::model_class);
}

void music::music_system::add_music(boost::shared_ptr<model::dom> node,
	boost::shared_ptr<network::i_socket> sock)
{
	boost::mutex::scoped_lock l(*_model->get_mutex());
	_model->get_clients().push_back(model::client(*node));
	_map[&_model->get_clients().back()] = sock;
}

void music::music_system::remove_music(
	boost::shared_ptr<network::i_socket> sock)
{
	boost::mutex::scoped_lock l(*_model->get_mutex());

	typedef map<model::client*, boost::shared_ptr<network::i_socket> >
		::iterator it;
	model::client *clt = 0;
	it del;
	for(it i = _map.begin(); i != _map.end(); ++i) {
		if(i->second == sock) {
			clt = i->first;
			del = i;
		}
	}

	if(clt == 0) {
		throw std::runtime_error("error, couldn't find client");
	}
		
	typedef list<model::client>::iterator it2;
	it2 i = _model->get_clients().begin();
	it2 next = _model->get_clients().begin();
	while(i != _model->get_clients().end()) {
		++next;
		if(&(*i) == clt) {
			_model->get_clients().erase(i);
		}
		i = next;
	}
	_map.erase(del);
}

boost::shared_ptr<network::i_socket> music::music_system::play_music(
						const string &client, 
						const string &file)
{
	boost::mutex::scoped_lock l(*_model->get_mutex());
	model::client *clt = _model->find_client(client);
	if(clt == 0) {
		throw std::runtime_error("error, couldn't find client");
	}

	model::title *title = _model->find_title(file, clt);
	if(title == 0) {
		throw std::runtime_error("error, couldn't find client");
	}
	boost::shared_ptr<model::title> t(title, core::null_deleter());

	file_streamer streamer(clt->get_name() + ".txt");
	streamer.append_title(t);

	return _map[clt];
}

string music::music_system::suggest_title(const string &client)
{
	boost::mutex::scoped_lock l(*_model->get_mutex());
	model::client *clt = _model->find_client(client);
	if(clt == 0) {
		throw std::runtime_error("error, couldn't find client");
	}
	boost::shared_ptr<model::client> clt_ptr(clt, core::null_deleter());

	boost::shared_ptr<music::data_miner> miner(new music::data_miner(
		clt_ptr, _model));
	miner->doit();
	boost::shared_ptr<model::title> t(miner->get_result());
	if(t.get() == 0) {
		return "";
	}
	return t->get_filename();
}

boost::shared_ptr<network::i_socket> music::music_system::get_socket(
							const string &client)
{
	model::client *clt = _model->find_client(client);
	if(clt == 0) {
		throw std::runtime_error("error, couldn't find client");
	}
	return _map[clt];
}

boost::shared_ptr<model::dom> music::music_system::list_clients() const
{
	boost::mutex::scoped_lock l(*_model->get_mutex());
	return _model->to_dom();
}

